package pri.black.config;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import pri.black.dogview.component.CacheService;
import pri.black.dogview.domain.Admin;
import pri.black.dogview.exception.BizException;
import pri.black.dogview.security.AdminDetails;
import pri.black.dogview.security.TokenAuthentication;
import pri.black.dogview.service.IAdminService;
import pri.black.dogview.util.ViewResolver;

import java.io.IOException;
import java.util.List;

@Slf4j
public class AuthFilter implements Filter {

    IAdminService adminService;

    CacheService cacheService;


    public AuthFilter(IAdminService adminService,CacheService cacheService) {
        this.adminService = adminService;
        this.cacheService = cacheService;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {

        if (req instanceof HttpServletRequest httpRequest && res instanceof HttpServletResponse httpServletResponse) {
            log.debug("request {} {}", httpRequest.getMethod(), httpRequest.getRequestURI());
            String authorization = httpRequest.getHeader("Authorization");
            if (!StringUtils.hasLength(authorization)) {

            } else {
                log.debug("token authorization {}", authorization);
                String prefix = "Bearer ";
                String token = null;
                if (authorization.startsWith(prefix)) {
                    token = authorization.substring(prefix.length()).trim();
                }else {
                    token = authorization.trim();
                }
//                Admin admin = adminService.lambdaQuery().eq(Admin::getToken, token).one();

                Object adminIdObj = cacheService.get("token:" + token);
                if (adminIdObj != null) {
                    Admin admin = adminService.getById((Long)adminIdObj);
                    UserDetails cached = new AdminDetails(admin);
                    TokenAuthentication authentication = new TokenAuthentication(cached);
                    authentication.setAuthenticated(true);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }else {

                }

            }
            try {
                filterChain.doFilter(req, res);
            } catch (AccessDeniedException e) {
                ViewResolver.resolve(httpRequest,httpServletResponse);
            } catch (BizException e) {
                ViewResolver.resolveError(httpRequest,httpServletResponse);
            } catch (Throwable e) {
                log.error("error ", e);
                ViewResolver.resolveError(httpRequest,httpServletResponse);
            }
        }else {
            filterChain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
